#include "comm.hpp"

// 程序在加载的时候，会自动构建全局变量，就要调用该类的构造函数从而创建管道文件，来保证访问控制功能共享内存
// 程序退出的时候，全局变量会被析构，自动调用析构函数，会自动删除管道文件
Init init;  

//TransToHex函数将key值转换为16进制，并返回。
string TransToHex(key_t k)
{
    char buffer[32];
    snprintf(buffer, sizeof buffer, "0x%x", k);
    return buffer;
}

int main()
{
    
    // 1. 创建公共的Key值
    key_t k = ftok(PATH_NAME, PROJ_ID);
    assert(k != -1);
    Log("create key done", Debug) << " server key : " << TransToHex(k) << endl;

    // 2. 创建共享内存 -- 建议要创建一个全新的共享内存 -- 通信的发起者
    int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666); 
    if (shmid == -1)
    {
        perror("shmget");
        exit(1);
    }
    Log("create shm done", Debug) << " shmid : " << shmid << endl;


    // 3. 将指定的共享内存，挂接到自己的地址空间
    char *shmaddr = (char *)shmat(shmid, nullptr, 0);
    Log("attach shm done", Debug) << " shmid : " << shmid << endl;

    //以读的方式打开管道文件
    int fd = OpenFIFO(FIFO_NAME, READ);
    for(;;)
    {
        //进程等待
        Wait(fd);
        // 临界区
        printf("%s\n", shmaddr); //shmaddr可以看作一个字符串指针
        if(strcmp(shmaddr, "quit") == 0) break;
    }

    // 4. 将指定的共享内存，从自己的地址空间中去关联
    int n = shmdt(shmaddr);
    assert(n != -1);
    (void)n;
    Log("detach shm done", Debug) << " shmid : " << shmid << endl;

    // 5. 删除共享内存,IPC_RMID即便是有进程和当下的shm挂接，依旧删除共享内存
    n = shmctl(shmid, IPC_RMID, nullptr);
    assert(n != -1);
    (void)n;
    Log("delete shm done", Debug) << " shmid : " << shmid << endl;

    CloseFifo(fd);
    return 0;
}